#property copyright "Copyright 2012"
#property link      "mingxinhe@gmail.com"

#property indicator_chart_window
#property indicator_buffers 4

//----
#define NONOE 0
#define Blue1ColourSignal 1
#define Red1ColourSignal 2
#define Blue2ColourSignal 3
#define Red2ColourSignal 4

extern int WPRPeriod = 14;
extern int RSIPeriod = 14;
extern double UpperLevel.WPR = -20; 
extern double LowerLevel.WPR = -80; 
extern double UpperLevel.RSI = 80; 
extern double LowerLevel.RSI = 20; 
extern color WPR.Color = Aqua;
extern color RSI.Color = DodgerBlue;
extern color Blue1ColourSignal.Color = Blue;
extern int   Blue1ColourSignal.Width = 1;
extern color Red1ColourSignal.Color = Red;
extern int   Red1ColourSignal.Width = 1;
extern color Blue2ColourSignal.Color = Green;
extern int   Blue2ColourSignal.Width = 2;
extern color Red2ColourSignal.Color = Pink;
extern int   Red2ColourSignal.Width = 2;

extern bool Text.Alert = true;
extern bool Sound.Alert = true;
extern bool Email.Alert = true;
extern string SoundFileName = "Alert.wav";


datetime lastCheck2ndBlueColourTime, lastCheck2ndRedColourTime;

bool Blue2ColourWPRFirstCondition = false;
bool Red2ColourWPRFirstCondition = false;
bool Blue2ColourRSIFirstCondition = false;
bool Red2ColourRSIFirstCondition = false;

bool CurBlue2ColourWPRFirstCondition = false;
bool CurBlue2ColourRSIFirstCondition = false;
bool CurRed2ColourWPRFirstCondition = false;
bool CurRed2ColourRSIFirstCondition = false;

bool CurBlue2ColourWPRSecondCond = false;
bool CurBlue2ColourRSISecondCond = false;
bool CurRed2ColourWPRSecondCond = false;
bool CurRed2ColourRSISecondCond = false;

//---- buffers
double upArrow1[];
double downArrow1[];
double upArrow2[];
double downArrow2[];
//---- buffers
double WPRBuffer[];
double RSIBuffer[];

int digitFactor = 1;
datetime lastTime;
bool upArrowSignal = false;
bool downArrowSignal = false;

int lastColourOneSignal = NONOE;
bool lastBlueColourTwoSignal, lastRedColourTwoSignal;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
  //---- 6 additional buffers are used for counting.   
   if(Bid<10 && Digits==5) { digitFactor=10;}
   if(Bid<10 && Digits==4) { digitFactor= 1;}

   if(Bid>10 && Digits==3) { digitFactor=10;}
   if(Bid>10 && Digits==2) { digitFactor= 1;} 
  
   IndicatorBuffers(6);   
//---- drawing settings 
   SetIndexStyle(0,DRAW_ARROW, EMPTY, Red1ColourSignal.Width, Red1ColourSignal.Color);
   SetIndexArrow(0,234);
   SetIndexBuffer(0, downArrow1);
   SetIndexEmptyValue(0,0);
      
   SetIndexStyle(1,DRAW_ARROW, EMPTY, Blue1ColourSignal.Width, Blue1ColourSignal.Color);
   SetIndexArrow(1,233);
   SetIndexBuffer(1, upArrow1);   
   SetIndexEmptyValue(1,0);
   
   SetIndexStyle(2,DRAW_ARROW, EMPTY, Red2ColourSignal.Width, Red2ColourSignal.Color);
   SetIndexArrow(2,234);
   SetIndexBuffer(2, downArrow2);
   SetIndexEmptyValue(2,0);
      
   SetIndexStyle(3,DRAW_ARROW, EMPTY, Blue2ColourSignal.Width, Blue2ColourSignal.Color);
   SetIndexArrow(3,233);
   SetIndexBuffer(3, upArrow2);  
   SetIndexEmptyValue(3,0); 
      
   SetIndexBuffer(4,WPRBuffer);
   SetIndexStyle(4,DRAW_LINE, EMPTY, 1,WPR.Color);
   SetIndexLabel(4, "W%R"); 
   
   SetIndexBuffer(5,RSIBuffer); 
   SetIndexStyle(5,DRAW_LINE, EMPTY, 1,RSI.Color); 
   SetIndexLabel(5, "RSI"); 
      
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));   
   
   lastColourOneSignal = NONOE;
//---- initialization done
   return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+

int deinit()
{
//---- TODO: add your code here
// --------------------------
//----
   return(0);
}

//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int start()
{  

   if(Bars<=WPRPeriod + RSIPeriod) return(0);
   
   int  counted_bars=IndicatorCounted();        
   if(counted_bars>0) 
   {
       int limit=Bars-counted_bars;
   }
   else
   {
       limit = Bars-(WPRPeriod+ RSIPeriod)+1;
   }       
      
   while(limit>=0)         
   {                                        
       WPRBuffer[limit]=iWPR(NULL,0,WPRPeriod,limit); 
       RSIBuffer[limit]=iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,limit);   
             
       if (limit==0)
       {
           double AvgRange = 0;       
            for (int counter=limit+1 ;counter<=limit+10;counter++)
            {
                AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
            }
            double Range=AvgRange/10;
       
           int newColourOneSignal = ColourOneSignal();
           if (lastColourOneSignal != newColourOneSignal)
           {
               if (newColourOneSignal != NONOE)
               {
                   doAlert(Symbol(), Period(), newColourOneSignal);
               }                                                
               
               lastColourOneSignal = newColourOneSignal;                                      
           }
           
           if (newColourOneSignal == Blue1ColourSignal) 
            {
                upArrow1[limit] = Low[limit] - Range*0.3;
                downArrow1[limit] = 0;
            }
            else if (newColourOneSignal == Red1ColourSignal) 
            {
                upArrow1[limit] = 0;
                downArrow1[limit] = High[limit] + Range*0.3;
            }
            else
            {
                upArrow1[limit] = 0;
                downArrow1[limit] = 0;
            }    
           
           bool newBlueColourTwoSignal = BlueColourTwoSignal();
           if (lastBlueColourTwoSignal != newBlueColourTwoSignal)
           {
               if (newBlueColourTwoSignal)
               {
                   doAlert(Symbol(), Period(), Blue2ColourSignal);                  
               }    
               
               lastBlueColourTwoSignal = newBlueColourTwoSignal;
           }
           if (newBlueColourTwoSignal)
            {                  
                upArrow2[limit] = Low[limit] - Range*0.8;
            }  
            else
            {
                upArrow2[limit] = 0;
            }    
           
           bool newRedColourTwoSignal = RedColourTwoSignal();
           if (lastRedColourTwoSignal != newRedColourTwoSignal)
           {
               if (newRedColourTwoSignal)
               {
                   doAlert(Symbol(), Period(), Red2ColourSignal);
               }    
               
               lastRedColourTwoSignal = newRedColourTwoSignal;
           }           
           if (newRedColourTwoSignal)
            {
                downArrow2[limit] = High[limit] + Range*0.8;
            }  
            else
            {
                downArrow2[limit] = 0;
            }    
       }    
       else
       {
            upArrow1[limit] = 0;
            downArrow1[limit] = 0;
            upArrow2[limit] = 0;
            downArrow2[limit] = 0;
       }
      
      limit--;
   }
      
//---- done
   return(0);  
}

string getTimeFrame(int _Period)
{
    switch (_Period)
    {
        case 1: return ("M1");
                break;
        case 5: return ("M5");
                break;
        case 15: return ("M15");
                break;
        case 30: return ("M30");
                break;
        case 60: return ("H1");
                break;
        case 240: return ("H4");
                break;
        case 1440: return ("D1");
                break;
        case 10080: return ("W1");
                break;
        case 43200: return ("Month");
                break;
    }
}

string getColorSignal(int colorSignal)
{
    switch (colorSignal)
    {
        case Blue1ColourSignal: return ("Blue1ColourSignal");
                break;
        case Blue2ColourSignal: return ("Blue2ColourSignal");
                break;
        case Red1ColourSignal: return ("Red1ColourSignal");
                break;
        case Red2ColourSignal: return ("Red2ColourSignal");
                break;
    }
}

void doAlert(string symbol, int timeFrame, int colorSignal)
{
      string alertStr = "Pair:" + symbol + ", T/F:" +  getTimeFrame(timeFrame) + ", Signal:" + getColorSignal(colorSignal);                   
      if (Text.Alert)
      {
          Alert(alertStr);
          Print(alertStr);
      }
      if (Email.Alert)
      {
          SendMail("Candle Pattern Alert" , alertStr);  
      }
      if (Sound.Alert)
      {
          PlaySound(SoundFileName);
      }   
}


int ColourOneSignal()
{
    if ((iWPR(NULL,0,WPRPeriod,0) == 0 || iWPR(NULL,0,WPRPeriod,0) > UpperLevel.WPR) && iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,0) > LowerLevel.RSI)
    {
        return (Blue1ColourSignal);
    }  
    
    if (iWPR(NULL,0,WPRPeriod,0) < LowerLevel.WPR && iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,0) < UpperLevel.RSI)
    {
        return (Red1ColourSignal);
    }  
   
   return (NONOE);
}

bool BlueColourTwoSignal()
{
    if (Time[0] > lastCheck2ndBlueColourTime)
    {
        CurBlue2ColourWPRFirstCondition = Blue2ColourWPRFirstCondition;
        CurBlue2ColourRSIFirstCondition = Blue2ColourRSIFirstCondition;
    
        Blue2ColourWPRFirstCondition = false;
        Blue2ColourRSIFirstCondition = false;
        
        CurBlue2ColourWPRSecondCond = false;        
        CurBlue2ColourRSISecondCond = false;        
        
        lastCheck2ndBlueColourTime = Time[0];
    }
    
    if (iWPR(NULL,0,WPRPeriod,0) < LowerLevel.WPR )
    {
        Blue2ColourWPRFirstCondition = true;
        CurBlue2ColourWPRFirstCondition = true;
    }  
    
    if (CurBlue2ColourWPRFirstCondition && iWPR(NULL,0,WPRPeriod,0) > UpperLevel.WPR)
    {
        CurBlue2ColourWPRSecondCond = true; 
    }
    
    if (iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,0) < LowerLevel.RSI )
    {
        Blue2ColourRSIFirstCondition = true;
        CurBlue2ColourRSIFirstCondition = true;
    }  
    
    if (CurBlue2ColourRSIFirstCondition && iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,0) > LowerLevel.RSI)
    {
        CurBlue2ColourRSISecondCond = true;   
    }

    if (CurBlue2ColourWPRFirstCondition && CurBlue2ColourWPRSecondCond && CurBlue2ColourRSIFirstCondition && CurBlue2ColourRSISecondCond) 
    {
        return (true);
    }
    
    return (false);   
}

bool RedColourTwoSignal()
{    
    if (Time[0] > lastCheck2ndRedColourTime)
    {
        CurRed2ColourWPRFirstCondition = Red2ColourWPRFirstCondition;
        CurRed2ColourRSIFirstCondition = Red2ColourRSIFirstCondition;
    
        Red2ColourWPRFirstCondition = false;
        Red2ColourRSIFirstCondition = false;
               
        CurRed2ColourWPRSecondCond = false;        
        CurRed2ColourRSISecondCond = false;
        
        lastCheck2ndRedColourTime = Time[0];
    }
    
    if (iWPR(NULL,0,WPRPeriod,0) > UpperLevel.WPR )
    {
        Red2ColourWPRFirstCondition = true;
        CurRed2ColourWPRFirstCondition = true;
    }  
    
    if (CurRed2ColourWPRFirstCondition && iWPR(NULL,0,WPRPeriod,0) < LowerLevel.WPR)
    {
        CurRed2ColourWPRSecondCond = true; 
    }
    
    if (iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,0) > UpperLevel.RSI )
    {
        Red2ColourRSIFirstCondition = true;
        CurRed2ColourRSIFirstCondition = true;
    }  
    
    if (CurRed2ColourRSIFirstCondition && iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,0) < UpperLevel.RSI)
    {
        CurRed2ColourRSISecondCond = true;   
    }

    if (CurRed2ColourWPRFirstCondition && CurRed2ColourWPRSecondCond && CurRed2ColourRSIFirstCondition && CurRed2ColourRSISecondCond) 
    {
        return (true);
    }
    
    return (false);   
}